﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="HashMap.ValueCollection.cs" company="JDML Consulting Ltd.">
//   Copyright 2011 Photon Project - http://photon.codeplex.com
// </copyright>
// <summary>
//   Defines the HashMap type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Photon.Collections
{
    using System;
    using System.Collections;
    using System.Collections.Generic;

    public partial class HashMap<TKey, TValue>
    {
        #region Nested type: ValueCollection

        private class ValueCollection : ICollection, ICollection<TValue>
        {
            #region Private Fields

            private readonly HashMap<TKey, TValue> _map;

            #endregion

            public ValueCollection(HashMap<TKey, TValue> map)
            {
                _map = map;
            }

            #region ICollection Members

            void ICollection.CopyTo(Array array, int index)
            {
                CollectionGuard.CopyToInvalidArguments(array, index, Count);
                foreach (var value in this)
                {
                    array.SetValue(value, index++);
                }
            }

            public int Count
            {
                get { return _map.Count; }
            }

            public object SyncRoot
            {
                get { return _map.SyncRoot; }
            }

            public bool IsSynchronized
            {
                get { return false; }
            }

            IEnumerator IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }

            #endregion

            #region ICollection<TValue> Members

            void ICollection<TValue>.Add(TValue item)
            {
                throw CollectionExceptions.CollectionIsReadOnly();
            }

            void ICollection<TValue>.Clear()
            {
                throw CollectionExceptions.CollectionIsReadOnly();
            }

            public bool Contains(TValue item)
            {
                return _map.ContainsValue(item);
            }

            public void CopyTo(TValue[] array, int arrayIndex)
            {
                CollectionGuard.CopyToInvalidArguments(array, arrayIndex, _map.Count);
                foreach (var value in this)
                {
                    array[arrayIndex++] = value;
                }
            }

            bool ICollection<TValue>.Remove(TValue item)
            {
                throw CollectionExceptions.CollectionIsReadOnly();
            }

            public bool IsReadOnly
            {
                get { return true; }
            }

            public IEnumerator<TValue> GetEnumerator()
            {
                return new ValueEnumerator(_map);
            }

            #endregion

            #region Nested type: ValueEnumerator

            /// <summary>
            /// ValueEnumerator, implemented manually rather than through yield to ensure 
            /// <see cref="IEnumerator{T}.Reset"/> is implemented.
            /// </summary>
            private class ValueEnumerator : IEnumerator<TValue>
            {
                private readonly Enumerator _enumerator;

                public ValueEnumerator(HashMap<TKey, TValue> map)
                {
                    _enumerator = new Enumerator(map);
                }

                #region IEnumerator<TValue> Members

                public void Reset()
                {
                    _enumerator.Reset();
                }

                public TValue Current
                {
                    get { return _enumerator.Current.Value; }
                }

                object IEnumerator.Current
                {
                    get { return Current; }
                }

                public bool MoveNext()
                {
                    return _enumerator.MoveNext();
                }

                public void Dispose()
                {
                }

                #endregion
            }

            #endregion
        }

        #endregion
    }
}